package com.sardine.base.esm;

import com.sardine.base.utils.JsonUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

/**
 * 北京京东世纪贸易有限公司<br>
 * Created with IntelliJ IDEA.
 * Date:2017/1/17
 * Time:17:26
 * ES 2.1.1 客户端
 * @author daifeng<br>
 *         daifeng@jd.com
 * @since JDK 1.7 <br>
 * Copyright (c) 2017 JD System Incorporated All Rights Reserved.
 */
public class ElasticsearchFactory {
    private static final Logger logger = LoggerFactory.getLogger(ElasticsearchFactory.class);


    /**集群名称*/
    private String clusterName;

    /**集群iP地址*/
    private String addressIp;

    /**es Client*/
    private Client client ;

    private boolean esSniff;


    public String index_reade;

    public String index_write;

    public String getIndex_reade() {
        return index_reade;
    }

    public void setIndex_reade(String index_reade) {
        this.index_reade = index_reade;
    }

    public String getIndex_write() {
        return index_write;
    }

    public void setIndex_write(String index_write) {
        this.index_write = index_write;
    }

    /**
     * 启动
     */
    @PostConstruct
    public void strt(){
        try {
            long s = System.currentTimeMillis();
            if(null == this.client){
                createClient();
            }
            long e = System.currentTimeMillis();
            logger.info("start es client ok time:{}毫秒", (e - s));
        } catch (Exception e) {
            logger.error("es client start fail.", e);
            System.exit(0);
        }
    }

    /**
     * 停止
     */
    @PreDestroy
    public void destory(){
        if(null != this.client){
            this.client.close();
            this.client = null;
        }
        logger.info("destory es client");
    }

    /**
     * 获取一个连接
     * @return
     */
    public Client getClient() {
        if(null ==	client){
            throw new RuntimeException("get es client fail, client is null");
        }
        return client;
    }

    /**
     * 创建一个 ES Client
     */
    private void createClient(){
        if(null != this.client){
            throw new RuntimeException("create Elasticsearch Client error, client is not null");
        }
        //创建ES客户端
        if(StringUtils.isEmpty(clusterName)){
            throw new RuntimeException("create Elasticsearch Client error clusterName is empty");
        }

        if(StringUtils.isEmpty(addressIp)){
            throw new RuntimeException("create Elasticsearch Client error addressIp is empty");
        }

        //解析ip地址
        List<Address> address = splitAddress();
        if(address.isEmpty()){
            throw new RuntimeException("create Elasticsearch Client error address is empty");
        }

        Settings settings;
        //开始创建
        if(esSniff){
            settings= Settings.settingsBuilder().put("client.transport.sniff", true)
                    .put("client.transport.ignore_cluster_name", true)
                    .put("cluster.name", clusterName).build();
        }else{
            settings = Settings.settingsBuilder()
                    .put("client.transport.ignore_cluster_name", true)
                    .put("cluster.name", clusterName).build();
        }
        TransportClient build = TransportClient.builder().settings(settings).build();
        for(Address addr : address){
            try {
                build.addTransportAddress(
                        new InetSocketTransportAddress(InetAddress.getByName(addr.getIp()), addr.getPort()));
                logger.info("connect ES Server Address:{}", JsonUtils.toJson(addr));
            } catch (UnknownHostException e) {
                logger.error("connect ES Server Address:{} error", JsonUtils.toJson(addr), e);
            }
        }
        client = build;
    }

    private List<Address> splitAddress(){
        List<Address> data = new ArrayList<Address>();
        String[] addressArray = this.addressIp.split(",");

        for(String add : addressArray){
            String[] tmp = add.split(":");
            Address address = new Address(tmp[0], Integer.parseInt(tmp[1]));
            data.add(address);
        }

        return data;
    }

    public String getClusterName() {
        return clusterName;
    }

    public void setClusterName(String clusterName) {
        this.clusterName = clusterName;
    }

    public String getAddressIp() {
        return addressIp;
    }

    public void setAddressIp(String addressIp) {
        this.addressIp = addressIp;
    }

    public boolean isEsSniff() {
        return esSniff;
    }

    public void setEsSniff(boolean esSniff) {
        this.esSniff = esSniff;
    }

    class Address{

        /**ip地址*/
        private String ip;

        /**端口*/
        private int port;

        Address(String ip, int port) {
            this.ip = ip;
            this.port = port;
        }

        public int getPort() {
            return port;
        }
        public void setPort(int port) {
            this.port = port;
        }

        public String getIp() {
            return ip;
        }
        public void setIp(String ip) {
            this.ip = ip;
        }
    }
}
